# @Time : 2021/5/26 13:39
# @Author : Fioman 
# @Phone : 13149920693
from db_tools.db_handler import DbHandler
from tools.save_image_to_device import *
from tools.config_params import ConfigParams
from tools.common_tools import image_to_string

"""
日志分析模块,主要是用来和生产日志那里进行通信的模块,日志分析,还有日志目录查看.
"""

cp = ConfigParams()


class LoggerTool(object):
    def __init__(self):
        self.logger = HdLogger()
        self.db = DbHandler()
        self.debugFileUsed = ""
        self.debugInfoList = []  # 日志显示总的记录内容,显示的时候,五十条五十条的显示,不要一下显示太多.
        self.debugInfoIdList = []  # 日志显示的所有的索引
        self.debugInfoShowTimes = 1  # 第几次显示日志.
        self.lineImageDir = ""  # 线阵相机显示的图片目录
        self.lineImageIndexList = []  # 线阵相机图片目录所有的图片编号
        self.lineImageWebShowIndex = 0  # 界面上显示的图像编号的索引值,用来下一张和上一张的时候,来切换不同的值
        self.cutterImageDir = ""  # 铡刀相机显示的图片目录.
        self.cutterImageIndexList = []  # 铡刀相机图片目录所有的图片编号
        self.cutterImageWebShowIndex = 0  # 界面上显示的图像编号的索引值,用来下一张和上一张的时候,来切换不同的值
        self.showDataLimit = 50  # 界面上展示的数据条目

    @staticmethod
    def get_all_debug_id(fileName):
        """
        根据debug文件的内容,获取所有的板子的编号
        :param fileName 要处理的debug的文件名
        :return:
        """
        totalIdList = []
        filePath = os.path.join(DEBUG_DIR, fileName)
        with open(filePath, encoding="utf-8") as f:
            while True:
                line = f.readline()
                if len(line) <= 0:
                    break
                if "id_" in line and " - " in line:
                    idFinded = line.split(" - ")[1].split(" ")[0][3:]
                    if idFinded not in totalIdList:
                        totalIdList.append(idFinded)
        return totalIdList

    @staticmethod
    def get_total_debug_file():
        """
        获取所有的日志文件名称
        :return:
        """
        debugFile = []
        for root, dirs, files in os.walk(DEBUG_DIR):
            for file in files:
                if root != DEBUG_DIR:
                    continue
                if file[-4:] == ".txt":
                    debugFile.append(file)
        return debugFile

    def get_debug_info_by_index(self, boardIndex):
        """
        根据板的编号获取日志信息
        :param boardIndex: 板编号
        :return:
        """
        debugInfoWeb = []
        debugFilePath = os.path.join(DEBUG_DIR, self.debugFileUsed)
        with open(debugFilePath, encoding='utf-8') as f:
            while True:
                line = f.readline()
                if len(line) <= 0:
                    break
                if boardIndex not in line:
                    continue
                timeInfoSplit = " - "
                if timeInfoSplit in line:
                    head = line.split(timeInfoSplit)[0]
                    content = line.split(timeInfoSplit)[1]
                else:
                    head = ""
                    content = line
                debugInfoWeb.append([head, content])

            return debugInfoWeb

    def get_debug_info_by_key_word(self, keyWord):
        debugInfoWeb = []
        debugFilePath = os.path.join(DEBUG_DIR, self.debugFileUsed)
        with open(debugFilePath, encoding='utf-8') as f:
            while True:
                line = f.readline()
                if len(line) <= 0:
                    break
                if keyWord not in line:
                    continue
                timeInfoSplit = " - "
                if timeInfoSplit in line:
                    head = line.split(timeInfoSplit)[0]
                    content = line.split(timeInfoSplit)[1]
                else:
                    head = ""
                    content = line
                debugInfoWeb.append([head, content])
        
            return debugInfoWeb

    def get_debug_info_by_hour_time(self, hourTime):
        """
        根据时间去获取日志,比较时间,如果大于这个时间,就从当前开始保存日志信息.
        :param hourTime: 时间的小时
        :return:
        """
        debugInfoWeb = []
        debugFilePath = os.path.join(DEBUG_DIR, self.debugFileUsed)
        timeIsRight = False
        with open(debugFilePath, encoding='utf-8') as f:
            while True:
                line = f.readline()
                if len(line) <= 0:
                    break
                if " - " not in line:
                    continue
                timeStr = line.split(" ")[1]
                hourFinded = int(timeStr[:2])
                minuteFinded = int(timeStr[3:5])
                secondFinded = int(timeStr[6:8])
                hour = int(hourTime[:2])
                minute = int(hourTime[3:5])
                second = int(hourTime[6:8])

                if not timeIsRight:
                    if hourFinded < hour:
                        continue
                    elif hourFinded == hour:
                        if minuteFinded < minute:
                            continue
                        elif minuteFinded == minute:
                            if secondFinded < second:
                                continue
                timeIsRight = True
                timeInfoSplit = " - "
                if timeInfoSplit in line:
                    head = line.split(timeInfoSplit)[0]
                    content = line.split(timeInfoSplit)[1]
                else:
                    head = ""
                    content = line
                debugInfoWeb.append([head, content])

            return debugInfoWeb

    @staticmethod
    def get_debug_info_by_name(debugFile):
        """
        根据文件名,获取日志文件.
        :param debugFile: 日志的文件名称.
        :return:
        """
        debugInfoWeb = []
        debugFilePath = os.path.join(DEBUG_DIR, debugFile)
        with open(debugFilePath, encoding="utf-8") as f:
            while True:
                line = f.readline()
                if len(line) <= 0:
                    break
                timeInfoSplit = " - "
                if timeInfoSplit in line:
                    head = line.split(timeInfoSplit)[0]
                    content = line.split(timeInfoSplit)[1]
                else:
                    head = ""
                    content = line
                debugInfoWeb.append([head, content])

            return debugInfoWeb

    def web_request_next_debug_info_page(self):
        """
        页面上点击了下一页日志信息.
        :return:
        """
        if len(self.debugInfoList) > 100:
            debugInfo = self.debugInfoList[:100]
            self.debugInfoList = self.debugInfoList[100:]
            debugInfoEndFlag = False
        else:
            debugInfo = self.debugInfoList
            debugInfoEndFlag = True

        return debugInfo, debugInfoEndFlag

    def web_request_get_logger_info(self, fileName):
        """
        前端界面请求了日志文件和内容
        :param fileName: 要显示的日志文件名称,如果是空,就默认显示第一条日志.
        :return:
        """
        # 获取所有的日志文件,并且按照日期进行排序.
        totalFiles = self.get_total_debug_file()
        totalFilesSortedByDate = sorted(totalFiles, reverse=True)
        if fileName == "":
            self.debugFileUsed = totalFilesSortedByDate[0]
        else:
            self.debugFileUsed = fileName

        debugInfo = self.get_debug_info_by_name(self.debugFileUsed)
        # 只选取最后面的100条数据进行展示,并且是倒叙的方式
        debugInfo = debugInfo[::-1]
        self.debugInfoList = debugInfo
        debugInfoEndFlag = True
        if len(debugInfo) > 100:
            debugInfo = debugInfo[:100]
            debugInfoEndFlag = False
        self.debugInfoList = self.debugInfoList[100:]  # 100往后面的个数,将前面100条数据搞掉
        boardIndexList = self.get_all_debug_id(self.debugFileUsed)
        self.debugInfoIdList = boardIndexList
        if len(boardIndexList) >= self.showDataLimit:
            boardIndexList = boardIndexList[:self.showDataLimit]
        return totalFilesSortedByDate, debugInfo, boardIndexList, debugInfoEndFlag

    def web_request_get_logger_info_by_board_index(self, boardIndex):
        """
        根据图像名称和物料的id来获取要显示的日志
        :param boardIndex 作业板的编号
        :return:
        """
        debugEndFlag = True
        id_boardIndex = "id_{}".format(boardIndex)
        debugInfo = self.get_debug_info_by_index(id_boardIndex)
        if len(debugInfo) == 0:
            debugInfo = [["日志id_{} ".format(boardIndex), "的日志记录不存在!"]]
        return debugInfo, debugEndFlag
    
    def web_request_get_logger_info_by_key_word(self,keyword):
        """
        根据关键字来获取要显示的日志
        :param keyword  关键字
        :return:
        """
        debugEndFlag = True
        debugInfo = self.get_debug_info_by_key_word(keyword)
        if len(debugInfo) == 0:
            debugInfo = [["关键字: {} ".format(keyword), "的日志记录不存在!"]]
        self.debugInfoList = debugInfo
        if len(debugInfo) >= 100:
            self.debugInfoList = debugInfo[100:]
            debugInfo = debugInfo[:100]
            debugEndFlag = False
        return debugInfo, debugEndFlag

    def web_request_get_logger_info_by_hour_time(self, timeHour):
        """
        前端界面上点击了按照时间去获取日志
        :param timeHour: 界面上选取的时间
        :return:
        """
        if timeHour == "":
            debugInfo = [["时间段_{}".format(timeHour), "不能为空"]]
        else:
            debugInfo = self.get_debug_info_by_hour_time(timeHour)
        if len(debugInfo) == 0:
            debugInfo = [["时间段_{}".format(timeHour), "的日志记录不存在"]]
        self.debugInfoList = debugInfo
        debugEndFlag = True
        if len(debugInfo) >= 100:
            self.debugInfoList = debugInfo[100:]
            debugInfo = debugInfo[:100]
            debugEndFlag = False
        return debugInfo, debugEndFlag

    @staticmethod
    def web_request_open_debug_dir():
        """
        前端界面点击了打开日志文件的目录.
        :return:
        """
        return open_debug_dir()

    def web_request_get_line_image_dir_board_list(self, dirName):
        """
        界面上获取图片目录下的所有的图片的id信息..
        :param dirName:
        :return:
        """
        if dirName == "切线":
            imageDir = RAW_CUT_LINE_DIR
        elif dirName == "识别失败":
            imageDir = RAW_FAIL_DIR
        elif dirName == "识别成功":
            imageDir = RAW_OK_DIR
        elif dirName == "首板":
            imageDir = FIRST_CUT_BOARD_DIR
        else:
            imageDir = RAW_TOTALBOARD_ERROR_DIR
        self.lineImageDir = imageDir
        # 遍历一个目录,并获取所有的图像编号.
        indexList = get_image_index_by_path(imageDir)
        indexList = sorted(indexList, key=lambda x: int(x.split("--")[0]))
        self.lineImageIndexList = indexList
        lineImageWebShow = indexList if len(indexList) <= self.showDataLimit else indexList[:self.showDataLimit]
        return lineImageWebShow

    def web_request_get_cutter_image_dir_board_list(self, dirName):
        """
        界面上获取铡刀图片目录下的所有的id信息
        :param dirName: 前端界面上展示的目录.
        :return:
        """
        if dirName == "起点检测原图":
            imageDir = CUTTER_RAW_BEGIN_DIR
        elif dirName == "起点检测结果图":
            imageDir = CUTTER_RAW_BEGIN_RES_DIR
        elif dirName == "终点检测原图":
            imageDir = CUTTER_RAW_FINAL_DIR
        else:
            imageDir = CUTTER_RAW_FINAL_RES_DIR
        # 遍历一个目录,并获取所有的图片编号
        self.cutterImageDir = imageDir
        indexList = get_image_index_by_path(imageDir)
        indexListSorted = sorted(indexList, key=lambda x: int(x.split("--")[0]))
        self.cutterImageIndexList = indexListSorted
        cutterImageWebShow = indexListSorted if len(indexListSorted) <= self.showDataLimit else indexListSorted[:self.showDataLimit]
        return cutterImageWebShow

    def web_request_search_image_index(self, searchIndex):
        """
        前端界面搜索框,后台返回搜索内容
        :param searchIndex: 搜索的index
        :return:
        """
        indexIsOk = [index for index in self.lineImageIndexList if searchIndex in index]
        return indexIsOk

    def web_request_search_debug_id_list(self, searchIndex):
        """
        前端界面搜索框,后台返回搜索内容
        :param searchIndex 搜索的索引编号
        :return:
        """
        indexIsOk = [index for index in self.debugInfoIdList if searchIndex in index]
        return indexIsOk

    def web_request_search_cutter_image_index(self, searchIndex):
        """
        前端界面搜索框,后台返回模糊搜索的内容
        :param searchIndex: 搜索的index,包括板编号和时间
        :return:
        """
        indexIsOk = [index for index in self.cutterImageIndexList if searchIndex in index]
        return indexIsOk

    def web_request_open_line_image_dir(self):
        """
        前端界面点击打开上料线阵图片的目录
        :return:
        """
        return open_dir_by_file_path(self.lineImageDir)

    def web_request_open_cutter_image_dir(self):
        """
        前端界面点击打开铡刀图片的目录
        :return:
        """
        return open_dir_by_file_path(self.cutterImageDir)

    @staticmethod
    def get_web_show_image_cutter(imageOriginal):
        """
        将要发送给前端的铡刀的图片,缩放比例,按照宽度是950进行缩放.
        :param imageOriginal:要发送给前端显示的铡刀的原图片
        :return:
        """
        h, w = imageOriginal.shape[:2]
        newWidth = 950
        newHeight = int(950 / w * h)
        imageSend = cv.resize(imageOriginal, (newWidth, newHeight), cv.INTER_AREA)
        imageSend = image_to_string(imageSend)
        return imageSend

    def get_web_show_image(self, imageOriginal):
        """
        将要发送给前端的原图,按照缩放比例,进行缩放,然后显示到前端
        :param imageOriginal: 要发送给前端显示的原图
        :return:
        """
        print("ImageOriginal = ({},{})".format(imageOriginal.shape[1], imageOriginal.shape[0]))
        h, w = imageOriginal.shape[:2]
        if self.lineImageDir != RAW_CUT_LINE_DIR:
            newWidth, newHeight = int(w / cp.sizeScale), int(h / cp.sizeScale)
            imageSend = cv.resize(imageOriginal, (newWidth, newHeight), cv.INTER_AREA)
        else:
            newWidth, newHeight = int(w * 2 / cp.sizeScale), int(h * 2 / cp.sizeScale)
            imageSend = cv.resize(imageOriginal, (newWidth, newHeight), cv.INTER_AREA)

        # 最大只能显示宽度1000,如果宽度超过了1000,就按照高宽比进行重新设定.
        if imageSend.shape[1] > 1000:
            newWidth = 1000
            newHeight = int(imageSend.shape[0] * (1000 / imageSend.shape[1]))
            imageSend = cv.resize(imageSend, (newWidth, newHeight), cv.INTER_AREA)
        print("boardSized = ({};{})".format(imageSend.shape[1], imageSend.shape[0]))
        imageSend = image_to_string(imageSend)
        return imageSend

    def web_request_cutter_image_pre_view(self, cutterImageIndex):
        """
        前端界面点击预览面阵相机的图片
        :param cutterImageIndex:图片的id和时间组成的字符串
        :return:
        """
        # 先获取图像的索引编号以及在列表self.cutterImageIndexList的索引值
        if cutterImageIndex in self.cutterImageIndexList:
            self.cutterImageWebShowIndex = self.cutterImageIndexList.index(cutterImageIndex)
            res, image, imageName = get_image_by_image_path_and_image_index(self.cutterImageDir, cutterImageIndex)
            if res:
                self.imagePreview = image
                imageSend = self.get_web_show_image_cutter(self.imagePreview)
                return True, imageSend, imageName
            else:
                return True, None, "图像编号: {} 的图像不存在".format(cutterImageIndex)
        else:
            return True, None, "图像编号: {} 的图像不存在".format(cutterImageIndex)

    def web_request_line_image_pre_view(self, lineImageIndex):
        """
        前端界面点击预览线阵相机的图片
        :param lineImageIndex: 图片的id号.
        :return:
        """
        # 先获取图像的索引编号,以及在列表self.lineImageIndexList的索引.
        if lineImageIndex in self.lineImageIndexList:
            self.lineImageWebShowIndex = self.lineImageIndexList.index(lineImageIndex)
            res, image, imageName = get_image_by_image_path_and_image_index(self.lineImageDir, lineImageIndex)
            if res:
                self.imagePreview = image
                imageSend = self.get_web_show_image(self.imagePreview)
                return True, imageSend, imageName
            else:
                return True, None, "图像编号:{}的图像不存在".format(lineImageIndex)
        else:
            return True, None, "图像编号:{}的图像不存在".format(lineImageIndex)

    def web_request_next_cutter_image_src(self):
        """
        界面上点击了预览下一张铡刀相机的图片
        :return:
        """
        indexMax = len(self.cutterImageIndexList)
        self.cutterImageWebShowIndex += 1
        if self.cutterImageWebShowIndex == indexMax:
            self.cutterImageWebShowIndex = 0

        cutterImageIndex = self.cutterImageIndexList[self.cutterImageWebShowIndex]
        res, image, imageName = get_image_by_image_path_and_image_index(self.cutterImageDir, cutterImageIndex)
        if res:
            self.imagePreview = image
            imageSend = self.get_web_show_image_cutter(self.imagePreview)
            return True, imageSend, imageName
        else:
            return True, None, "图像编号: {} 的图像不存在".format(cutterImageIndex)

    def web_request_last_cutter_image_src(self):
        """
        界面上点击了预览上一张铡刀相机的图片
        :return:
        """
        indexMax = len(self.cutterImageIndexList)
        self.cutterImageWebShowIndex -= 1
        if self.cutterImageWebShowIndex < 0:
            self.cutterImageWebShowIndex = indexMax - 1
        cutterImageIndex = self.cutterImageIndexList[self.cutterImageWebShowIndex]
        res, image, imageName = get_image_by_image_path_and_image_index(self.cutterImageDir, cutterImageIndex)
        if res:
            self.imagePreview = image
            imageSend = self.get_web_show_image_cutter(self.imagePreview)
            return True, imageSend, imageName
        else:
            return True, None, "图像编号: {} 的图像不存在".format(cutterImageIndex)

    def web_request_next_line_image_src(self):
        """
        前端界面点击预览下一张线阵相机的图片.
        :return:
        """
        indexMax = len(self.lineImageIndexList)
        self.lineImageWebShowIndex += 1
        if self.lineImageWebShowIndex == indexMax:
            self.lineImageWebShowIndex = 0

        lineImageIndex = self.lineImageIndexList[self.lineImageWebShowIndex]
        res, image, imageName = get_image_by_image_path_and_image_index(self.lineImageDir, lineImageIndex)
        if res:
            self.imagePreview = image
            imageSend = self.get_web_show_image(self.imagePreview)
            return True, imageSend, imageName
        else:
            return True, None, "图像编号:{}的图像不存在".format(lineImageIndex)

    def web_request_last_line_image_src(self):
        """
        前端界面点击预览上一张线阵相机的图片
        :return:
        """
        indexMax = len(self.lineImageIndexList)
        self.lineImageWebShowIndex -= 1
        if self.lineImageWebShowIndex < 0:
            self.lineImageWebShowIndex = indexMax - 1
        lineImageIndex = self.lineImageIndexList[self.lineImageWebShowIndex]
        res, image, imageName = get_image_by_image_path_and_image_index(self.lineImageDir, lineImageIndex)
        if res:
            self.imagePreview = image
            imageSend = self.get_web_show_image(self.imagePreview)
            return True, imageSend, imageName
        else:
            return True, None, "图像编号:{}的图像不存在".format(lineImageIndex)

    def web_request_copy_cutter_file_to_file_save_dir(self, indexTimeStr):
        """
        根据文件名去获取铡刀的图片
        :param indexTimeStr: 图像编号和时间组成的字符串
        :return:
        """
        if indexTimeStr == "inPreview":
            indexTimeStr = self.cutterImageIndexList[self.cutterImageWebShowIndex]
        if indexTimeStr in self.cutterImageIndexList:
            res, image, imageName = get_image_by_image_path_and_image_index(self.cutterImageDir, indexTimeStr)
            if res:
                newImagePath = os.path.join(FILE_SAVE_DIR, imageName)
                cv.imwrite(newImagePath, image)
                return "ok"
            else:
                return "图像编号: {} 的图像不存在".format(indexTimeStr)
        else:
            return "图像编号: {} 的图像不存在".format(indexTimeStr)

    def web_request_copy_file_to_file_save_dir(self, indexTimeStr):
        """
        根据文件名去复制这张图片.
        :param indexTimeStr:要复制的图片的开始的字符串名称
        :return:
        """
        if indexTimeStr == "inPreview":
            indexTimeStr = self.lineImageIndexList[self.lineImageWebShowIndex]
        if indexTimeStr in self.lineImageIndexList:
            res, image, imageName = get_image_by_image_path_and_image_index(self.lineImageDir, indexTimeStr)
            if res:
                newImagePath = os.path.join(FILE_SAVE_DIR, imageName)
                cv.imwrite(newImagePath, image)
                return "ok"
            else:
                return "图像编号:{}的图像不存在".format(indexTimeStr)
        else:
            return "图像编号:{}的图像不存在".format(indexTimeStr)

    @staticmethod
    def web_request_open_file_save_dir():
        """
        前端界面点击了打开临时保存图片的目录,打开我们用来保存的自己想保存的图片.
        :return:
        """
        return open_dir_by_file_path(FILE_SAVE_DIR)

    @staticmethod
    def web_request_clear_file_save_dir():
        """
        界面上点击了清空临时保存的目录.
        :return:
        """
        for root, dirs, files in os.walk(FILE_SAVE_DIR):
            for file in files:
                if root != FILE_SAVE_DIR:
                    continue
                os.remove(os.path.join(FILE_SAVE_DIR, file))
        return "ok"

    def web_request_get_produce_amount_record(self):
        """
        前端界面获取月产量的请求
        :return:
        """
        res, data = self.db.get_produce_record_table_data()
        if res != "ok":
            return []
        recordList = [data.get(str(i)) for i in range(1, 13)]
        webShowDataList = [(str((index + 1)) + "月", data) for index, data in enumerate(recordList)]

        dayAmountDict = data.get("dayAmount")
        newDayAmountTableVal = []
        tableDataIndex1 = "dayIndex"
        tableDataIndex2 = "dayAmount"
        dayAmountDictKey = dayAmountDict.keys()
        newAmountDictKey = sorted(dayAmountDictKey, reverse=True)
        nowDay = get_time_now_string()[5:10]
        if len(newAmountDictKey) > 31:  # 如果超过了31天
            nowDayIndex = newAmountDictKey.index(nowDay)
            newAmountDictKey = newAmountDictKey[nowDayIndex:]
        if len(newAmountDictKey) >= 31:
            newAmountDictKey = newAmountDictKey[:32]

        newAmountDict = {key: dayAmountDict[key] for key in newAmountDictKey}

        for key, val in newAmountDict.items():
            newVal = {
                "key": key,
                tableDataIndex1: key,
                tableDataIndex2: val
            }
            newDayAmountTableVal.append(newVal)

        return webShowDataList, newDayAmountTableVal


if __name__ == '__main__':
    hdlt = LoggerTool()
    hdlt.web_request_get_logger_info("")
    idList = hdlt.get_all_debug_id("2021-05-23_debug.txt")
    print(idList)
    hdlt.web_request_get_line_image_dir_board_list("识别失败")
